# common/db_util.py
import os
import json
import pymysql
from pymysql.cursors import DictCursor
from common.read_config import read_config


class DatabaseValidator:
    """数据库数据校验工具类，支持多系统区分"""

    def __init__(self, system_name: str):
        """
        初始化数据库连接
        :param system_name: 系统名称（testcases/lemangCase）
        """
        self.system_name = system_name
        self.conn = self._create_connection()

    def _create_connection(self):
        """根据系统名称创建对应数据库连接"""
        # 读取对应系统的数据库配置
        section = f"{self.system_name}_db" if self.system_name == "lemangCase" else "test_db"

        try:
            # 从配置文件读取数据库参数
            db_config = {
                "host": read_config(section, "host"),
                "port": int(read_config(section, "port")),
                "user": read_config(section, "user"),
                "passwordWD": read_config(section, "password"),
                "database": read_config(section, "database"),
                "charset": "utf8mb4"
            }

            # 创建数据库连接
            conn = pymysql.connect(
                **db_config,
                cursorclass=DictCursor  # 返回字典格式结果
            )
            print(f"✅ {self.system_name} 系统数据库连接成功")
            return conn
        except Exception as e:
            raise ConnectionError(f"❌ {self.system_name} 系统数据库连接失败: {str(e)}")

    def query(self, sql: str, params=None) -> list:
        """
        执行查询SQL
        :param sql: SQL语句
        :param params: SQL参数（防止注入）
        :return: 查询结果列表
        """
        try:
            with self.conn.cursor() as cursor:
                cursor.execute(sql, params or ())
                result = cursor.fetchall()
                print(f"📋 SQL执行成功: {sql}")
                return result
        except Exception as e:
            raise RuntimeError(f"❌ SQL执行失败: {str(e)}")

    def validate_data(self, sql: str, expected_data: dict, compare_keys: list = None) -> bool:
        """
        校验数据库数据是否符合预期
        :param sql: 查询SQL
        :param expected_data: 预期数据字典
        :param compare_keys: 需要对比的字段列表（None则对比所有字段）
        :return: 校验结果（True/False）
        """
        # 获取实际数据
        actual_data_list = self.query(sql)
        if not actual_data_list:
            raise AssertionError("查询结果为空，无法进行校验")

        # 取第一条数据进行校验（可根据需要调整）
        actual_data = actual_data_list[0]

        # 确定需要对比的字段
        check_keys = compare_keys or expected_data.keys()

        # 逐个字段校验
        for key in check_keys:
            actual_value = actual_data.get(key)
            expected_value = expected_data.get(key)

            assert actual_value == expected_value, \
                f"字段校验失败: 系统={self.system_name}, 字段={key}, " \
                f"预期={expected_value}, 实际={actual_value}"

        print(f"✅ 数据校验通过: {self.system_name}")
        return True

    def close(self):
        """关闭数据库连接"""
        if self.conn:
            self.conn.close()
            print(f"🔌 {self.system_name} 数据库连接已关闭")

    def __enter__(self):
        """支持上下文管理器"""
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        """自动关闭连接"""
        self.close()


# 便捷工具函数
def get_db_validator(system_name: str) -> DatabaseValidator:
    """
    获取指定系统的数据库校验器
    :param system_name: 系统名称（testcases/lemangCase）
    :return: DatabaseValidator实例
    """
    return DatabaseValidator(system_name)